home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / src / gas-211 / gas / expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  31.2 KB  |  1,159 lines

  1. /* expr.c -operands, expressions-
  2.    Copyright (C) 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  19.  
  20. /*
  21.  * This is really a branch office of as-read.c. I split it out to clearly
  22.  * distinguish the world of expressions from the world of statements.
  23.  * (It also gives smaller files to re-compile.)
  24.  * Here, "operand"s are of expressions, not instructions.
  25.  */
  26.  
  27. #include <ctype.h>
  28. #include <string.h>
  29.  
  30. #include "as.h"
  31.  
  32. #include "obstack.h"
  33.  
  34. static void clean_up_expression PARAMS ((expressionS * expressionP));
  35. extern const char EXP_CHARS[], FLT_CHARS[];
  36.  
  37. /*
  38.  * Build any floating-point literal here.
  39.  * Also build any bignum literal here.
  40.  */
  41.  
  42. /* Seems atof_machine can backscan through generic_bignum and hit whatever
  43.    happens to be loaded before it in memory.  And its way too complicated
  44.    for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
  45.    and never write into the early words, thus they'll always be zero.
  46.    I hate Dean's floating-point code.  Bleh.  */
  47. LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
  48. FLONUM_TYPE generic_floating_point_number =
  49. {
  50.   &generic_bignum[6],        /* low (JF: Was 0) */
  51.   &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1],    /* high JF: (added +6) */
  52.   0,                /* leader */
  53.   0,                /* exponent */
  54.   0                /* sign */
  55. };
  56. /* If nonzero, we've been asked to assemble nan, +inf or -inf */
  57. int generic_floating_point_magic;
  58.  
  59. floating_constant (expressionP)
  60.      expressionS *expressionP;
  61. {
  62.   /* input_line_pointer->*/
  63.   /* floating-point constant. */
  64.   int error_code;
  65.  
  66.   error_code = atof_generic
  67.     (&input_line_pointer, ".", EXP_CHARS,
  68.      &generic_floating_point_number);
  69.  
  70.   if (error_code)
  71.     {
  72.       if (error_code == ERROR_EXPONENT_OVERFLOW)
  73.     {
  74.       as_bad ("bad floating-point constant: exponent overflow, probably assembling junk");
  75.     }
  76.       else
  77.     {
  78.       as_bad ("bad floating-point constant: unknown error code=%d.", error_code);
  79.     }
  80.     }
  81.   expressionP->X_seg = big_section;
  82.   /* input_line_pointer->just after constant, */
  83.   /* which may point to whitespace. */
  84.   expressionP->X_add_number = -1;
  85. }
  86.  
  87.  
  88.  
  89. integer_constant (radix, expressionP)
  90.      int radix;
  91.      expressionS *expressionP;
  92. {
  93.   register char *digit_2;    /*->2nd digit of number. */
  94.   char c;
  95.  
  96.   register valueT number;    /* offset or (absolute) value */
  97.   register short int digit;    /* value of next digit in current radix */
  98.   register short int maxdig = 0;/* highest permitted digit value. */
  99.   register int too_many_digits = 0;    /* if we see >= this number of */
  100.   register char *name;        /* points to name of symbol */
  101.   register symbolS *symbolP;    /* points to symbol */
  102.  
  103.   int small;            /* true if fits in 32 bits. */
  104.   extern const char hex_value[]; /* in hex_value.c */
  105.  
  106.   /* may be bignum, or may fit in 32 bits. */
  107.   /*
  108.    * most numbers fit into 32 bits, and we want this case to be fast.
  109.    * so we pretend it will fit into 32 bits. if, after making up a 32
  110.    * bit number, we realise that we have scanned more digits than
  111.    * comfortably fit into 32 bits, we re-scan the digits coding
  112.    * them into a bignum. for decimal and octal numbers we are conservative: some
  113.    * numbers may be assumed bignums when in fact they do fit into 32 bits.
  114.    * numbers of any radix can have excess leading zeros: we strive
  115.    * to recognise this and cast them back into 32 bits.
  116.    * we must check that the bignum really is more than 32
  117.    * bits, and change it back to a 32-bit number if it fits.
  118.    * the number we are looking for is expected to be positive, but
  119.    * if it fits into 32 bits as an unsigned number, we let it be a 32-bit
  120.    * number. the cavalier approach is for speed in ordinary cases.
  121.    */
  122.  
  123.   switch (radix)
  124.     {
  125.  
  126.     case 2:
  127.       maxdig = 2;
  128.       too_many_digits = 33;
  129.       break;
  130.     case 8:
  131.       maxdig = radix = 8;
  132.       too_many_digits = 11;
  133.       break;
  134.     case 16:
  135.  
  136.  
  137.       maxdig = radix = 16;
  138.       too_many_digits = 9;
  139.       break;
  140.     case 10:
  141.       maxdig = radix = 10;
  142.       too_many_digits = 11;
  143.     }
  144.   c = *input_line_pointer;
  145.   input_line_pointer++;
  146.   digit_2 = input_line_pointer;
  147.   for (number = 0; (digit = hex_value[c]) < maxdig; c = *input_line_pointer++)
  148.     {
  149.       number = number * radix + digit;
  150.     }
  151.   /* c contains character after number. */
  152.   /* input_line_pointer->char after c. */
  153.   small = input_line_pointer - digit_2 < too_many_digits;
  154.   if (!small)
  155.     {
  156.       /*
  157.        * we saw a lot of digits. manufacture a bignum the hard way.
  158.        */
  159.       LITTLENUM_TYPE *leader;    /*->high order littlenum of the bignum. */
  160.       LITTLENUM_TYPE *pointer;    /*->littlenum we are frobbing now. */
  161.       long carry;
  162.  
  163.       leader = generic_bignum;
  164.       generic_bignum[0] = 0;
  165.       generic_bignum[1] = 0;
  166.       /* we could just use digit_2, but lets be mnemonic. */
  167.       input_line_pointer = --digit_2;    /*->1st digit. */
  168.       c = *input_line_pointer++;
  169.       for (; (carry = hex_value[c]) < maxdig; c = *input_line_pointer++)
  170.     {
  171.       for (pointer = generic_bignum;
  172.            pointer <= leader;
  173.            pointer++)
  174.         {
  175.           long work;
  176.  
  177.           work = carry + radix * *pointer;
  178.           *pointer = work & LITTLENUM_MASK;
  179.           carry = work >> LITTLENUM_NUMBER_OF_BITS;
  180.         }
  181.       if (carry)
  182.         {
  183.           if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
  184.         {        /* room to grow a longer bignum. */
  185.           *++leader = carry;
  186.         }
  187.         }
  188.     }
  189.       /* again, c is char after number, */
  190.       /* input_line_pointer->after c. */
  191.       know (sizeof (int) * 8 == 32);
  192.       know (LITTLENUM_NUMBER_OF_BITS == 16);
  193.       /* hence the constant "2" in the next line. */
  194.       if (leader < generic_bignum + 2)
  195.     {            /* will fit into 32 bits. */
  196.       number =
  197.         ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
  198.         | (generic_bignum[0] & LITTLENUM_MASK);
  199.       small = 1;
  200.     }
  201.       else
  202.     {
  203.       number = leader - generic_bignum + 1;    /* number of littlenums in the bignum. */
  204.     }
  205.     }
  206.   if (small)
  207.     {
  208.       /*
  209.        * here with number, in correct radix. c is the next char.
  210.        * note that unlike un*x, we allow "011f" "0x9f" to
  211.        * both mean the same as the (conventional) "9f". this is simply easier
  212.        * than checking for strict canonical form. syntax sux!
  213.        */
  214.  
  215.       switch (c)
  216.     {
  217.  
  218. #ifdef LOCAL_LABELS_FB
  219.     case 'b':
  220.       {
  221.         /*
  222.          * backward ref to local label.
  223.          * because it is backward, expect it to be defined.
  224.          */
  225.         /* Construct a local label.  */
  226.         name = fb_label_name ((int) number, 0);
  227.  
  228.         /* seen before, or symbol is defined: ok */
  229.         symbolP = symbol_find (name);
  230.         if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
  231.           {
  232.  
  233.         /* local labels are never absolute. don't waste time
  234.            checking absoluteness. */
  235.         know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
  236.  
  237.         expressionP->X_add_symbol = symbolP;
  238.         expressionP->X_seg = S_GET_SEGMENT (symbolP);
  239.  
  240.           }
  241.         else
  242.           {            /* either not seen or not defined. */
  243.         as_bad ("backw. ref to unknown label \"%d:\", 0 assumed.", number);
  244.         expressionP->X_seg = absolute_section;
  245.           }
  246.  
  247.         expressionP->X_add_number = 0;
  248.         break;
  249.       }            /* case 'b' */
  250.  
  251.     case 'f':
  252.       {
  253.         /*
  254.          * forward reference. expect symbol to be undefined or
  255.          * unknown. undefined: seen it before. unknown: never seen
  256.          * it before.
  257.          * construct a local label name, then an undefined symbol.
  258.          * don't create a xseg frag for it: caller may do that.
  259.          * just return it as never seen before.
  260.          */
  261.         name = fb_label_name ((int) number, 1);
  262.         symbolP = symbol_find_or_make (name);
  263.         /* we have no need to check symbol properties. */
  264. #ifndef many_segments
  265.         /* since "know" puts its arg into a "string", we
  266.            can't have newlines in the argument.  */
  267.         know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
  268. #endif
  269.         expressionP->X_add_symbol = symbolP;
  270.         expressionP->X_seg = undefined_section;
  271.         expressionP->X_subtract_symbol = NULL;
  272.         expressionP->X_add_number = 0;
  273.  
  274.         break;
  275.       }            /* case 'f' */
  276.  
  277. #endif /* LOCAL_LABELS_FB */
  278.  
  279. #ifdef LOCAL_LABELS_DOLLAR
  280.  
  281.     case '$':
  282.       {
  283.  
  284.         /* If the dollar label is *currently* defined, then this is just
  285.            another reference to it.  If it is not *currently* defined,
  286.            then this is a fresh instantiation of that number, so create
  287.            it.  */
  288.  
  289.         if (dollar_label_defined (number))
  290.           {
  291.         name = dollar_label_name (number, 0);
  292.         symbolP = symbol_find (name);
  293.         know (symbolP != NULL);
  294.           }
  295.         else
  296.           {
  297.         name = dollar_label_name (number, 1);
  298.         symbolP = symbol_find_or_make (name);
  299.           }
  300.  
  301.         expressionP->X_add_symbol = symbolP;
  302.         expressionP->X_add_number = 0;
  303.         expressionP->X_seg = S_GET_SEGMENT (symbolP);
  304.  
  305.         break;
  306.       }            /* case '$' */
  307.  
  308. #endif /* LOCAL_LABELS_DOLLAR */
  309.  
  310.     default:
  311.       {
  312.         expressionP->X_add_number = number;
  313.         expressionP->X_seg = absolute_section;
  314.         input_line_pointer--;    /* restore following character. */
  315.         break;
  316.       }            /* really just a number */
  317.  
  318.     }            /* switch on char following the number */
  319.  
  320.  
  321.     }
  322.   else
  323.     {                /* not a small number */
  324.       expressionP->X_add_number = number;
  325.       expressionP->X_seg = big_section;
  326.       input_line_pointer--;    /*->char following number. */
  327.     }                /* if (small) */
  328. }                /* integer_constant() */
  329.  
  330.  
  331. /*
  332.  * Summary of operand().
  333.  *
  334.  * in:    Input_line_pointer points to 1st char of operand, which may
  335.  *    be a space.
  336.  *
  337.  * out:    A expressionS. X_seg determines how to understand the rest of the
  338.  *    expressionS.
  339.  *    The operand may have been empty: in this case X_seg == SEG_ABSENT.
  340.  *    Input_line_pointer->(next non-blank) char after operand.
  341.  *
  342.  */
  343.  
  344.  
  345.  
  346. static segT
  347. operand (expressionP)
  348.      register expressionS *expressionP;
  349. {
  350.   register char c;
  351.   register symbolS *symbolP;    /* points to symbol */
  352.   register char *name;        /* points to name of symbol */
  353.   /* invented for humans only, hope */
  354.   /* optimising compiler flushes it! */
  355.   register short int radix;    /* 2, 8, 10 or 16, 0 when floating */
  356.   /* 0 means we saw start of a floating- */
  357.   /* point constant. */
  358.  
  359.   /* digits, assume it is a bignum. */
  360.  
  361.   SKIP_WHITESPACE ();        /* leading whitespace is part of operand. */
  362.   c = *input_line_pointer++;    /* input_line_pointer->past char in c. */
  363.  
  364.   switch (c)
  365.     {
  366. #ifdef MRI
  367.     case '%':
  368.       integer_constant (2, expressionP);
  369.       break;
  370.     case '@':
  371.       integer_constant (8, expressionP);
  372.       break;
  373.     case '$':
  374.       integer_constant (16, expressionP);
  375.       break;
  376. #endif
  377.     case '1':
  378.     case '2':
  379.     case '3':
  380.     case '4':
  381.     case '5':
  382.     case '6':
  383.     case '7':
  384.     case '8':
  385.     case '9':
  386.       input_line_pointer--;
  387.  
  388.       integer_constant (10, expressionP);
  389.       break;
  390.  
  391.     case '0':
  392.       /* non-decimal radix */
  393.  
  394.  
  395.       c = *input_line_pointer;
  396.       switch (c)
  397.     {
  398.  
  399.     default:
  400.       if (c && strchr (FLT_CHARS, c))
  401.         {
  402.           input_line_pointer++;
  403.           floating_constant (expressionP);
  404.         }
  405.       else
  406.         {
  407.           /* The string was only zero */
  408.           expressionP->X_add_symbol = 0;
  409.           expressionP->X_add_number = 0;
  410.           expressionP->X_seg = absolute_section;
  411.         }
  412.  
  413.       break;
  414.  
  415.     case 'x':
  416.     case 'X':
  417.       input_line_pointer++;
  418.       integer_constant (16, expressionP);
  419.       break;
  420.  
  421.     case 'b':
  422. #ifdef LOCAL_LABELS_FB
  423.       if (!*input_line_pointer
  424.           || (!strchr ("+-.0123456789", *input_line_pointer)
  425.           && !strchr (EXP_CHARS, *input_line_pointer)))
  426.         {
  427.           input_line_pointer--;
  428.           integer_constant (10, expressionP);
  429.           break;
  430.         }
  431. #endif
  432.     case 'B':
  433.       input_line_pointer++;
  434.       integer_constant (2, expressionP);
  435.       break;
  436.  
  437.     case '0':
  438.     case '1':
  439.     case '2':
  440.     case '3':
  441.     case '4':
  442.     case '5':
  443.     case '6':
  444.     case '7':
  445.       integer_constant (8, expressionP);
  446.       break;
  447.  
  448.     case 'f':
  449. #ifdef LOCAL_LABELS_FB
  450.       /* if it says '0f' and the line ends or it doesn't look like
  451.          a floating point #, its a local label ref.  dtrt */
  452.       /* likewise for the b's.  xoxorich. */
  453.       if (c == 'f'
  454.           && (!*input_line_pointer ||
  455.           (!strchr ("+-.0123456789", *input_line_pointer) &&
  456.            !strchr (EXP_CHARS, *input_line_pointer))))
  457.         {
  458.           input_line_pointer -= 1;
  459.           integer_constant (10, expressionP);
  460.           break;
  461.         }
  462. #endif
  463.  
  464.     case 'd':
  465.     case 'D':
  466.     case 'F':
  467.     case 'r':
  468.     case 'e':
  469.     case 'E':
  470.     case 'g':
  471.     case 'G':
  472.  
  473.       input_line_pointer++;
  474.       floating_constant (expressionP);
  475.       expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);
  476.       break;
  477.  
  478. #ifdef LOCAL_LABELS_DOLLAR
  479.     case '$':
  480.       integer_constant (10, expressionP);
  481.       break;
  482. #endif
  483.     }
  484.  
  485.       break;
  486.     case '(':
  487.       /* didn't begin with digit & not a name */
  488.       {
  489.     (void) expression (expressionP);
  490.     /* Expression() will pass trailing whitespace */
  491.     if (*input_line_pointer++ != ')')
  492.       {
  493.         as_bad ("Missing ')' assumed");
  494.         input_line_pointer--;
  495.       }
  496.     /* here with input_line_pointer->char after "(...)" */
  497.       }
  498.       return expressionP->X_seg;
  499.  
  500.  
  501.     case '\'':
  502.       /* Warning: to conform to other people's assemblers NO ESCAPEMENT is
  503.      permitted for a single quote. The next character, parity errors and
  504.      all, is taken as the value of the operand. VERY KINKY.  */
  505.       expressionP->X_add_number = *input_line_pointer++;
  506.       expressionP->X_seg = absolute_section;
  507.       break;
  508.  
  509.     case '+':
  510.       operand (expressionP);
  511.       break;
  512.  
  513.     case '~':
  514.     case '-':
  515.       {
  516.     /* unary operator: hope for SEG_ABSOLUTE */
  517.     segT opseg = operand (expressionP);
  518.     if (opseg == absolute_section)
  519.       {
  520.         /* input_line_pointer -> char after operand */
  521.         if (c == '-')
  522.           {
  523.         expressionP->X_add_number = -expressionP->X_add_number;
  524.         /* Notice: '-' may overflow: no warning is given. This is
  525.            compatible with other people's assemblers. Sigh.  */
  526.           }
  527.         else
  528.           {
  529.         expressionP->X_add_number = ~expressionP->X_add_number;
  530.           }
  531.       }
  532.     else if (opseg == text_section
  533.          || opseg == data_section
  534.          || opseg == bss_section
  535.          || opseg == pass1_section
  536.          || opseg == undefined_section)
  537.       {
  538.         if (c == '-')
  539.           {
  540.         expressionP->X_subtract_symbol = expressionP->X_add_symbol;
  541.         expressionP->X_add_symbol = 0;
  542.         expressionP->X_seg = diff_section;
  543.           }
  544.         else
  545.           as_warn ("Unary operator %c ignored because bad operand follows",
  546.                c);
  547.       }
  548.     else
  549.       as_warn ("Unary operator %c ignored because bad operand follows", c);
  550.       }
  551.       break;
  552.  
  553.     case '.':
  554.       if (!is_part_of_name (*input_line_pointer))
  555.     {
  556.       char *fake;
  557.       extern struct obstack frags;
  558.  
  559.       /* JF: '.' is pseudo symbol with value of current location
  560.          in current segment.  */
  561. #ifdef DOT_LABEL_PREFIX
  562.       fake = ".L0\001";
  563. #else
  564.       fake = "L0\001";
  565. #endif
  566.       symbolP = symbol_new (fake,
  567.                 now_seg,
  568.            (valueT) (obstack_next_free (&frags) - frag_now->fr_literal),
  569.                 frag_now);
  570.  
  571.       expressionP->X_add_number = 0;
  572.       expressionP->X_add_symbol = symbolP;
  573.       expressionP->X_seg = now_seg;
  574.       break;
  575.  
  576.     }
  577.       else
  578.     {
  579.       goto isname;
  580.  
  581.  
  582.     }
  583.     case ',':
  584.     case '\n':
  585.     case '\0':
  586.     eol:
  587.       /* can't imagine any other kind of operand */
  588.       expressionP->X_seg = absent_section;
  589.       input_line_pointer--;
  590.       md_operand (expressionP);
  591.       break;
  592.  
  593.     default:
  594.       if (is_end_of_line[c])
  595.     goto eol;
  596.       if (is_name_beginner (c))    /* here if did not begin with a digit */
  597.     {
  598.       /*
  599.        * Identifier begins here.
  600.        * This is kludged for speed, so code is repeated.
  601.        */
  602.     isname:
  603.       name = --input_line_pointer;
  604.       c = get_symbol_end ();
  605.       symbolP = symbol_find_or_make (name);
  606.       /* If we have an absolute symbol or a reg, then we know its value
  607.          now.  */
  608.       expressionP->X_seg = S_GET_SEGMENT (symbolP);
  609.       if (expressionP->X_seg == absolute_section
  610.           || expressionP->X_seg == reg_section)
  611.         expressionP->X_add_number = S_GET_VALUE (symbolP);
  612.       else
  613.         {
  614.           expressionP->X_add_number = 0;
  615.           expressionP->X_add_symbol = symbolP;
  616.         }
  617.       *input_line_pointer = c;
  618.       expressionP->X_subtract_symbol = NULL;
  619.     }
  620.       else
  621.     {
  622.       as_bad ("Bad expression");
  623.       expressionP->X_add_number = 0;
  624.       expressionP->X_seg = absolute_section;
  625.     }
  626.     }
  627.  
  628.   /*
  629.    * It is more 'efficient' to clean up the expressionS when they are created.
  630.    * Doing it here saves lines of code.
  631.    */
  632.   clean_up_expression (expressionP);
  633.   SKIP_WHITESPACE ();        /*->1st char after operand. */
  634.   know (*input_line_pointer != ' ');
  635.   return (expressionP->X_seg);
  636. }                /* operand() */
  637.  
  638.  
  639. /* Internal. Simplify a struct expression for use by expr() */
  640.  
  641. /*
  642.  * In:    address of a expressionS.
  643.  *    The X_seg field of the expressionS may only take certain values.
  644.  *    Now, we permit SEG_PASS1 to make code smaller & faster.
  645.  *    Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
  646.  * Out:    expressionS may have been modified:
  647.  *    'foo-foo' symbol references cancelled to 0,
  648.  *        which changes X_seg from SEG_DIFFERENCE to SEG_ABSOLUTE;
  649.  *    Unused fields zeroed to help expr().
  650.  */
  651.  
  652. static void
  653. clean_up_expression (expressionP)
  654.      register expressionS *expressionP;
  655. {
  656.   segT s = expressionP->X_seg;
  657.   if (s == absent_section
  658.       || s == pass1_section)
  659.     {
  660.       expressionP->X_add_symbol = NULL;
  661.       expressionP->X_subtract_symbol = NULL;
  662.       expressionP->X_add_number = 0;
  663.     }
  664.   else if (s == big_section
  665.        || s == absolute_section)
  666.     {
  667.       expressionP->X_subtract_symbol = NULL;
  668.       expressionP->X_add_symbol = NULL;
  669.     }
  670.   else if (s == undefined_section)
  671.     expressionP->X_subtract_symbol = NULL;
  672.   else if (s == diff_section)
  673.     {
  674.       /*
  675.        * It does not hurt to 'cancel' NULL==NULL
  676.        * when comparing symbols for 'eq'ness.
  677.        * It is faster to re-cancel them to NULL
  678.        * than to check for this special case.
  679.        */
  680.       if (expressionP->X_subtract_symbol == expressionP->X_add_symbol
  681.       || (expressionP->X_subtract_symbol
  682.           && expressionP->X_add_symbol
  683.           && (expressionP->X_subtract_symbol->sy_frag
  684.           == expressionP->X_add_symbol->sy_frag)
  685.           && (S_GET_VALUE (expressionP->X_subtract_symbol)
  686.           == S_GET_VALUE (expressionP->X_add_symbol))))
  687.     {
  688.       expressionP->X_subtract_symbol = NULL;
  689.       expressionP->X_add_symbol = NULL;
  690.       expressionP->X_seg = absolute_section;
  691.     }
  692.     }
  693.   else if (s == reg_section)
  694.     {
  695.       expressionP->X_add_symbol = NULL;
  696.       expressionP->X_subtract_symbol = NULL;
  697.     }
  698.   else
  699.     {
  700.       if (SEG_NORMAL (expressionP->X_seg))
  701.     {
  702.       expressionP->X_subtract_symbol = NULL;
  703.     }
  704.       else
  705.     {
  706.       BAD_CASE (expressionP->X_seg);
  707.     }
  708.     }
  709. }
  710.  
  711. /*
  712.  *            expr_part ()
  713.  *
  714.  * Internal. Made a function because this code is used in 2 places.
  715.  * Generate error or correct X_?????_symbol of expressionS.
  716.  */
  717.  
  718. /*
  719.  * symbol_1 += symbol_2 ... well ... sort of.
  720.  */
  721.  
  722. static segT
  723. expr_part (symbol_1_PP, symbol_2_P)
  724.      symbolS **symbol_1_PP;
  725.      symbolS *symbol_2_P;
  726. {
  727.   segT return_value;
  728. #ifndef MANY_SEGMENTS
  729. #ifndef OBJ_ECOFF
  730.   int test = ((*symbol_1_PP) == NULL
  731.           || (S_GET_SEGMENT (*symbol_1_PP) == text_section)
  732.           || (S_GET_SEGMENT (*symbol_1_PP) == data_section)
  733.           || (S_GET_SEGMENT (*symbol_1_PP) == bss_section)
  734.           || (!S_IS_DEFINED (*symbol_1_PP)));
  735.   assert (test);
  736.   test = (symbol_2_P == NULL
  737.       || (S_GET_SEGMENT (symbol_2_P) == text_section)
  738.       || (S_GET_SEGMENT (symbol_2_P) == data_section)
  739.       || (S_GET_SEGMENT (symbol_2_P) == bss_section)
  740.       || (!S_IS_DEFINED (symbol_2_P)));
  741.   assert (test);
  742. #endif
  743. #endif
  744.   if (*symbol_1_PP)
  745.     {
  746.       if (!S_IS_DEFINED (*symbol_1_PP))
  747.     {
  748.       if (symbol_2_P)
  749.         {
  750.           return_value = pass1_section;
  751.           *symbol_1_PP = NULL;
  752.         }
  753.       else
  754.         {
  755.           know (!S_IS_DEFINED (*symbol_1_PP));
  756.           return_value = undefined_section;
  757.         }
  758.     }
  759.       else
  760.     {
  761.       if (symbol_2_P)
  762.         {
  763.           if (!S_IS_DEFINED (symbol_2_P))
  764.         {
  765.           *symbol_1_PP = NULL;
  766.           return_value = pass1_section;
  767.         }
  768.           else
  769.         {
  770.           /* {seg1} - {seg2} */
  771.           as_bad ("Expression too complex, 2 symbolS forgotten: \"%s\" \"%s\"",
  772.             S_GET_NAME (*symbol_1_PP), S_GET_NAME (symbol_2_P));
  773.           *symbol_1_PP = NULL;
  774.           return_value = absolute_section;
  775.         }
  776.         }
  777.       else
  778.         {
  779.           return_value = S_GET_SEGMENT (*symbol_1_PP);
  780.         }
  781.     }
  782.     }
  783.   else
  784.     {                /* (* symbol_1_PP) == NULL */
  785.       if (symbol_2_P)
  786.     {
  787.       *symbol_1_PP = symbol_2_P;
  788.       return_value = S_GET_SEGMENT (symbol_2_P);
  789.     }
  790.       else
  791.     {
  792.       *symbol_1_PP = NULL;
  793.       return_value = absolute_section;
  794.     }
  795.     }
  796. #ifndef MANY_SEGMENTS
  797. #ifndef OBJ_ECOFF
  798.   test = (return_value == absolute_section
  799.       || return_value == text_section
  800.       || return_value == data_section
  801.       || return_value == bss_section
  802.       || return_value == undefined_section
  803.       || return_value == pass1_section);
  804.   assert (test);
  805. #endif
  806. #endif
  807.   know ((*symbol_1_PP) == NULL
  808.     || (S_GET_SEGMENT (*symbol_1_PP) == return_value));
  809.   return (return_value);
  810. }
  811.  
  812. /* Expression parser. */
  813.  
  814. /*
  815.  * We allow an empty expression, and just assume (absolute,0) silently.
  816.  * Unary operators and parenthetical expressions are treated as operands.
  817.  * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
  818.  *
  819.  * We used to do a aho/ullman shift-reduce parser, but the logic got so
  820.  * warped that I flushed it and wrote a recursive-descent parser instead.
  821.  * Now things are stable, would anybody like to write a fast parser?
  822.  * Most expressions are either register (which does not even reach here)
  823.  * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
  824.  * So I guess it doesn't really matter how inefficient more complex expressions
  825.  * are parsed.
  826.  *
  827.  * After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
  828.  * Also, we have consumed any leading or trailing spaces (operand does that)
  829.  * and done all intervening operators.
  830.  */
  831.  
  832. typedef enum
  833. {
  834.   O_illegal,            /* (0)  what we get for illegal op */
  835.  
  836.   O_multiply,            /* (1)  * */
  837.   O_divide,            /* (2)  / */
  838.   O_modulus,            /* (3)  % */
  839.   O_left_shift,            /* (4)  < */
  840.   O_right_shift,        /* (5)  > */
  841.   O_bit_inclusive_or,        /* (6)  | */
  842.   O_bit_or_not,            /* (7)  ! */
  843.   O_bit_exclusive_or,        /* (8)  ^ */
  844.   O_bit_and,            /* (9)  & */
  845.   O_add,            /* (10) + */
  846.   O_subtract            /* (11) - */
  847. }
  848.  
  849. operatorT;
  850.  
  851. #define __ O_illegal
  852.  
  853. static const operatorT op_encoding[256] =
  854. {                /* maps ASCII->operators */
  855.  
  856.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  857.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  858.  
  859.   __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
  860.   __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
  861.   __, __, __, __, __, __, __, __,
  862.   __, __, __, __, O_left_shift, __, O_right_shift, __,
  863.   __, __, __, __, __, __, __, __,
  864.   __, __, __, __, __, __, __, __,
  865.   __, __, __, __, __, __, __, __,
  866.   __, __, __, __, __, __, O_bit_exclusive_or, __,
  867.   __, __, __, __, __, __, __, __,
  868.   __, __, __, __, __, __, __, __,
  869.   __, __, __, __, __, __, __, __,
  870.   __, __, __, __, O_bit_inclusive_or, __, __, __,
  871.  
  872.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  873.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  874.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  875.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  876.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  877.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  878.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  879.   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
  880. };
  881.  
  882.  
  883. /*
  884.  *    Rank    Examples
  885.  *    0    operand, (expression)
  886.  *    1    + -
  887.  *    2    & ^ ! |
  888.  *    3    * / % << >>
  889.  */
  890. static const operator_rankT
  891.   op_rank[] =
  892. {0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1};
  893.  
  894. /* Return resultP->X_seg. */
  895. segT 
  896. expr (rank, resultP)
  897.      register operator_rankT rank;    /* Larger # is higher rank. */
  898.      register expressionS *resultP;    /* Deliver result here. */
  899. {
  900.   expressionS right;
  901.   register operatorT op_left;
  902.   register char c_left;        /* 1st operator character. */
  903.   register operatorT op_right;
  904.   register char c_right;
  905.  
  906.   know (rank >= 0);
  907.   (void) operand (resultP);
  908.   know (*input_line_pointer != ' ');    /* Operand() gobbles spaces. */
  909.   c_left = *input_line_pointer;    /* Potential operator character. */
  910.   op_left = op_encoding[c_left];
  911.   while (op_left != O_illegal && op_rank[(int) op_left] > rank)
  912.     {
  913.       input_line_pointer++;    /*->after 1st character of operator. */
  914.       /* Operators "<<" and ">>" have 2 characters. */
  915.       if (*input_line_pointer == c_left && (c_left == '<' || c_left == '>'))
  916.     {
  917.       input_line_pointer++;
  918.     }            /*->after operator. */
  919.       if (absent_section == expr (op_rank[(int) op_left], &right))
  920.     {
  921.       as_warn ("Missing operand value assumed absolute 0.");
  922.       resultP->X_add_number = 0;
  923.       resultP->X_subtract_symbol = NULL;
  924.       resultP->X_add_symbol = NULL;
  925.       resultP->X_seg = absolute_section;
  926.     }
  927.       know (*input_line_pointer != ' ');
  928.       c_right = *input_line_pointer;
  929.       op_right = op_encoding[c_right];
  930.       if (*input_line_pointer == c_right && (c_right == '<' || c_right == '>'))
  931.     {
  932.       input_line_pointer++;
  933.     }            /*->after operator. */
  934.       know ((int) op_right == 0 || op_rank[(int) op_right] <= op_rank[(int) op_left]);
  935.       /* input_line_pointer->after right-hand quantity. */
  936.       /* left-hand quantity in resultP */
  937.       /* right-hand quantity in right. */
  938.       /* operator in op_left. */
  939.       if (resultP->X_seg == pass1_section || right.X_seg == pass1_section)
  940.     {
  941.       resultP->X_seg = pass1_section;
  942.     }
  943.       else
  944.     {
  945.       if (resultP->X_seg == big_section)
  946.         {
  947.           as_warn ("Left operand of %c is a %s.  Integer 0 assumed.",
  948.             c_left, resultP->X_add_number > 0 ? "bignum" : "float");
  949.           resultP->X_seg = absolute_section;
  950.           resultP->X_add_symbol = 0;
  951.           resultP->X_subtract_symbol = 0;
  952.           resultP->X_add_number = 0;
  953.         }
  954.       if (right.X_seg == big_section)
  955.         {
  956.           as_warn ("Right operand of %c is a %s.  Integer 0 assumed.",
  957.                c_left, right.X_add_number > 0 ? "bignum" : "float");
  958.           right.X_seg = absolute_section;
  959.           right.X_add_symbol = 0;
  960.           right.X_subtract_symbol = 0;
  961.           right.X_add_number = 0;
  962.         }
  963.       if (op_left == O_subtract)
  964.         {
  965.           /*
  966.            * Convert - into + by exchanging symbolS and negating number.
  967.            * I know -infinity can't be negated in 2's complement:
  968.            * but then it can't be subtracted either. This trick
  969.            * does not cause any further inaccuracy.
  970.            */
  971.  
  972.           register symbolS *symbolP;
  973.  
  974.           right.X_add_number = -right.X_add_number;
  975.           symbolP = right.X_add_symbol;
  976.           right.X_add_symbol = right.X_subtract_symbol;
  977.           right.X_subtract_symbol = symbolP;
  978.           if (symbolP)
  979.         {
  980.           right.X_seg = diff_section;
  981.         }
  982.           op_left = O_add;
  983.         }
  984.  
  985.       if (op_left == O_add)
  986.         {
  987.           segT seg1;
  988.           segT seg2;
  989. #ifndef MANY_SEGMENTS
  990. #ifndef OBJ_ECOFF
  991.           know (resultP->X_seg == data_section || resultP->X_seg == text_section || resultP->X_seg == bss_section || resultP->X_seg == undefined_section || resultP->X_seg == diff_section || resultP->X_seg == absolute_section || resultP->X_seg == pass1_section || resultP->X_seg == reg_section);
  992.  
  993.           know (right.X_seg == data_section || right.X_seg == text_section || right.X_seg == bss_section || right.X_seg == undefined_section || right.X_seg == diff_section || right.X_seg == absolute_section || right.X_seg == pass1_section);
  994. #endif
  995. #endif
  996.           clean_up_expression (&right);
  997.           clean_up_expression (resultP);
  998.  
  999.           seg1 = expr_part (&resultP->X_add_symbol, right.X_add_symbol);
  1000.           seg2 = expr_part (&resultP->X_subtract_symbol, right.X_subtract_symbol);
  1001.           if (seg1 == pass1_section || seg2 == pass1_section)
  1002.         {
  1003.           need_pass_2 = 1;
  1004.           resultP->X_seg = pass1_section;
  1005.         }
  1006.           else if (seg2 == absolute_section)
  1007.         resultP->X_seg = seg1;
  1008.           else if (seg1 != undefined_section
  1009.                && seg1 != absolute_section
  1010.                && seg2 != undefined_section
  1011.                && seg1 != seg2)
  1012.         {
  1013.           know (seg2 != absolute_section);
  1014.           know (resultP->X_subtract_symbol);
  1015. #ifndef MANY_SEGMENTS
  1016. #ifndef OBJ_ECOFF
  1017.           know (seg1 == text_section || seg1 == data_section || seg1 == bss_section);
  1018.           know (seg2 == text_section || seg2 == data_section || seg2 == bss_section);
  1019. #endif
  1020. #endif
  1021.           know (resultP->X_add_symbol);
  1022.           know (resultP->X_subtract_symbol);
  1023.           as_bad ("Expression too complex: forgetting %s - %s",
  1024.               S_GET_NAME (resultP->X_add_symbol),
  1025.               S_GET_NAME (resultP->X_subtract_symbol));
  1026.           resultP->X_seg = absolute_section;
  1027.           /* Clean_up_expression() will do the rest. */
  1028.         }
  1029.           else
  1030.         resultP->X_seg = diff_section;
  1031.  
  1032.           resultP->X_add_number += right.X_add_number;
  1033.           clean_up_expression (resultP);
  1034.         }
  1035.       else
  1036.         {            /* Not +. */
  1037.           if (resultP->X_seg == undefined_section || right.X_seg == undefined_section)
  1038.         {
  1039.           resultP->X_seg = pass1_section;
  1040.           need_pass_2 = 1;
  1041.         }
  1042.           else
  1043.         {
  1044.           resultP->X_subtract_symbol = NULL;
  1045.           resultP->X_add_symbol = NULL;
  1046.           /* Will be absolute_section. */
  1047.           if (resultP->X_seg != absolute_section || right.X_seg != absolute_section)
  1048.             {
  1049.               as_bad ("Relocation error. Absolute 0 assumed.");
  1050.               resultP->X_seg = absolute_section;
  1051.               resultP->X_add_number = 0;
  1052.             }
  1053.           else
  1054.             {
  1055.               switch (op_left)
  1056.             {
  1057.             case O_bit_inclusive_or:
  1058.               resultP->X_add_number |= right.X_add_number;
  1059.               break;
  1060.  
  1061.             case O_modulus:
  1062.               if (right.X_add_number)
  1063.                 {
  1064.                   resultP->X_add_number %= right.X_add_number;
  1065.                 }
  1066.               else
  1067.                 {
  1068.                   as_warn ("Division by 0. 0 assumed.");
  1069.                   resultP->X_add_number = 0;
  1070.                 }
  1071.               break;
  1072.  
  1073.             case O_bit_and:
  1074.               resultP->X_add_number &= right.X_add_number;
  1075.               break;
  1076.  
  1077.             case O_multiply:
  1078.               resultP->X_add_number *= right.X_add_number;
  1079.               break;
  1080.  
  1081.             case O_divide:
  1082.               if (right.X_add_number)
  1083.                 {
  1084.                   resultP->X_add_number /= right.X_add_number;
  1085.                 }
  1086.               else
  1087.                 {
  1088.                   as_warn ("Division by 0. 0 assumed.");
  1089.                   resultP->X_add_number = 0;
  1090.                 }
  1091.               break;
  1092.  
  1093.             case O_left_shift:
  1094.               resultP->X_add_number <<= right.X_add_number;
  1095.               break;
  1096.  
  1097.             case O_right_shift:
  1098.               resultP->X_add_number >>= right.X_add_number;
  1099.               break;
  1100.  
  1101.             case O_bit_exclusive_or:
  1102.               resultP->X_add_number ^= right.X_add_number;
  1103.               break;
  1104.  
  1105.             case O_bit_or_not:
  1106.               resultP->X_add_number |= ~right.X_add_number;
  1107.               break;
  1108.  
  1109.             default:
  1110.               BAD_CASE (op_left);
  1111.               break;
  1112.             }    /* switch(operator) */
  1113.             }
  1114.         }        /* If we have to force need_pass_2. */
  1115.         }            /* If operator was +. */
  1116.     }            /* If we didn't set need_pass_2. */
  1117.       op_left = op_right;
  1118.     }                /* While next operator is >= this rank. */
  1119.   return (resultP->X_seg);
  1120. }
  1121.  
  1122. /*
  1123.  *            get_symbol_end()
  1124.  *
  1125.  * This lives here because it belongs equally in expr.c & read.c.
  1126.  * Expr.c is just a branch office read.c anyway, and putting it
  1127.  * here lessens the crowd at read.c.
  1128.  *
  1129.  * Assume input_line_pointer is at start of symbol name.
  1130.  * Advance input_line_pointer past symbol name.
  1131.  * Turn that character into a '\0', returning its former value.
  1132.  * This allows a string compare (RMS wants symbol names to be strings)
  1133.  * of the symbol name.
  1134.  * There will always be a char following symbol name, because all good
  1135.  * lines end in end-of-line.
  1136.  */
  1137. char
  1138. get_symbol_end ()
  1139. {
  1140.   register char c;
  1141.  
  1142.   while (is_part_of_name (c = *input_line_pointer++))
  1143.     ;
  1144.   *--input_line_pointer = 0;
  1145.   return (c);
  1146. }
  1147.  
  1148.  
  1149. unsigned int 
  1150. get_single_number ()
  1151. {
  1152.   expressionS exp;
  1153.   operand (&exp);
  1154.   return exp.X_add_number;
  1155.  
  1156. }
  1157.  
  1158. /* end of expr.c */
  1159.